# -*- coding: utf-8 -*-
import hashlib
import json

import requests
from django.conf import settings

from common.utils import exceptions as err
from common.utils import track_logging
from common.withdraw.model import WITHDRAW_ORDER_STATUS
from datetime import datetime


_LOGGER = track_logging.getLogger('withdraw')

_GATEWAY = 'https://www.qijipay.com/apiWithdrawNew'

APP_CONF = {
    '100107': {
        'NAME': 'DUROTAR',
        'API_KEY': 'zTtfthiqZpVakEaO',
    },
    '100109': {
        'NAME': 'WITCH',
        'API_KEY': 'xnaDtfQsHogdGRzW',
    },
    '100106': {
        'NAME': 'LOKI',
        'API_KEY': 'WsGhAzUJZdqjTjwY',
    },
    '100110': {
        'NAME': 'ZS',
        'API_KEY': 'xJgbFGjRFPmBYFon',
    },
    '100096': {
        'NAME': 'SP',
        'API_KEY': 'kvxuwZurJBaiPkSm',
    },
}


def _get_api_key(app_id):
    return APP_CONF[app_id]['API_KEY']


def create_order(order, channel):
    ''' 奇迹代付下单 '''
    app_id = channel.appid
    app_key = _get_api_key(app_id)
    data = {
        "MemberID": int(app_id),
    }
    data['data'] = [{
        "code_id": str(order.id),
        "user_name": order.pay_account_username,
        "true_name": order.pay_account_username,
        "account": order.pay_account_num,
        "bank_info": "%s%s" % (order.pay_account_bank, order.pay_account_bank_subbranch),
        "money": str(order.amount),
        "return_url": settings.QIJI_NOTIFY_URL + app_id
    }]

    # stupid sign
    sign_str = '{"MemberID":%s,"data":[{"code_id":"%s","user_name":"%s","true_name":"%s","account":"%s","bank_info":"%s","money":"%s","return_url":"%s"}]}' % (
        app_id, int(order.id), order.pay_account_username, order.pay_account_username, order.pay_account_num,
        "%s%s" % (order.pay_account_bank, order.pay_account_bank_subbranch), order.amount,
        settings.QIJI_NOTIFY_URL + app_id)

    sign_str = sign_str.replace("\n", "")

    data['signature'] = generate_sign(sign_str + _get_api_key(app_id))
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    _LOGGER.info("qiji withdraw create order: %s" % data)

    # 先设置为三方未知状态
    order.status = WITHDRAW_ORDER_STATUS.THIRD_UNKNOWN
    order.third_type = channel.id
    order.save()

    response = requests.post(_GATEWAY, data=json.dumps(data), headers=headers, timeout=5)
    _LOGGER.info("qiji withdraw create rsp: %s", response.text)
    res_dict = json.loads(response.text)
    if int(res_dict['result_code']) == 1:
        order.status = WITHDRAW_ORDER_STATUS.THIRD
        order.extra_info = response.text
        order.save()
        return True
    else:
        order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        order.extra_info = response.text
        order.save()
        return False


def generate_sign(s):
    _LOGGER.info('sign string: %s' % s)
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().lower()
    return sign


def _verify_notify_sign(data, app_id, order):
    key = _get_api_key(app_id)
    sign = data['sign']
    bardbank_num = order.pay_account_num
    bank_name = "%s%s" % (order.pay_account_bank, order.pay_account_bank_subbranch)
    s = '{}|{}|{}|{}|{}|{}|{}|{}|{}'.format(
        data['business_num'], key, data['code_id'], data['user_name'].encode('utf8'), data['user_name'].encode('utf8'),
        bardbank_num, data['money'], bank_name.encode('utf8'), settings.QIJI_NOTIFY_URL + app_id,
    ).decode('utf8')
    _LOGGER.info("qiji withdraw sign str: %s ", s)
    calculated_sign = generate_sign(s)
    if sign != calculated_sign:
        _LOGGER.info("qiji withdraw sign: %s, calculated sign: %s", sign, calculated_sign)
        raise err.ParamError('qiji sign not pass, data: %s' % data)


def check_bankcard_withdraw_notify(data, app_id, order):
    ''' 奇迹代付回调 '''
    _LOGGER.info('qiji bankcard callback, app_id: %s, notify_data : %s' % (app_id, data))
    _verify_notify_sign(data, app_id, order)
    order_id = data['code_id']
    trade_status = int(data['status'])
    if not order:
        raise err.ParamError('qiji bankcard withdraw event does not contain valid order ID')

    if trade_status == 1:
        _LOGGER.info('qiji success: %s' % data)
        order.status = WITHDRAW_ORDER_STATUS.DONE
        order.extra_info = json.dumps(data)
        order.third_notify_at = datetime.utcnow()
        order.save()
        return True
    elif trade_status in [2, 3]:
        _LOGGER.info('qiji fail: %s' % data)
        order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        order.extra_info = json.dumps(data)
        order.third_notify_at = datetime.utcnow()
        order.save()
        return False
    else:
        raise err.ParamError('status invalid')
